#include "gptapi.h"

size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)userp;

    // 扩展内存以容纳新数据
    char *ptr = realloc(mem->memory, mem->size + realsize + 1);
    if (!ptr) {
        fprintf(stderr, "内存不足！\n");
        return 0;
    }
    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = '\0';

    // 解析事件数据
    char *buffer = mem->memory;
    char *end;

    while ((end = strstr(buffer, "\n\n"))) {
        *end = '\0';  // 临时截断字符串

        // 提取事件数据，跳过 "data: "
        if (strncmp(buffer, "data: ", 6) == 0) {
            const char *event_data = buffer + 6;
            process_event(event_data);
        }

        buffer = end + 2;  // 移动到下一个事件
    }

    // 将未处理的数据移到缓冲区开头
    size_t remaining = mem->size - (buffer - mem->memory);
    memmove(mem->memory, buffer, remaining);
    mem->size = remaining;
    mem->memory[mem->size] = '\0';
    return realsize;
}

// 处理服务器推送的事件
void process_event(const char *event_data) {
    if (strcmp(event_data, "[DONE]") == 0) {
        //printf("\n");
        return;
    }

    cJSON *json = cJSON_Parse(event_data);
    if (!json) {
        printf("JSON解析错误: %s\n", cJSON_GetErrorPtr());
        return;
    }

    cJSON *choices = cJSON_GetObjectItem(json, "choices");
    if (choices && cJSON_IsArray(choices) && cJSON_GetArraySize(choices) > 0) {
        cJSON *first_choice = cJSON_GetArrayItem(choices, 0);
        cJSON *delta = cJSON_GetObjectItem(first_choice, "delta");
        if (delta) {
            cJSON *content = cJSON_GetObjectItem(delta, "content");
            if (content && cJSON_IsString(content)) {
                printf("%s", content->valuestring);
                fflush(stdout);
            }
        }
    }

    cJSON_Delete(json);
}

void gpt_read_code(char* mode_name, char* require, char* text, uint8_t mode){
    CURL *curl;
    CURLcode res;

    struct MemoryStruct chunk;
    chunk.memory = malloc(1);
    chunk.size = 0;

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();

    if (curl) {
        // 设置API端点
        curl_easy_setopt(curl, CURLOPT_URL, "https://api.mindcraft.com.cn/v1/chat/completions");

        // 设置请求头
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        headers = curl_slist_append(headers, "Authorization: Bearer MC-62F6042A1FCC42548F7023ED1FBEBDD6");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // 构建请求体
        cJSON *request = cJSON_CreateObject();
        cJSON_AddStringToObject(request, "model", mode_name);

        cJSON *messages = cJSON_CreateArray();
        cJSON *system_msg = cJSON_CreateObject();
        cJSON_AddStringToObject(system_msg, "role", "system");
        cJSON_AddStringToObject(system_msg, "content", require);
        cJSON_AddItemToArray(messages, system_msg);

        cJSON *user_msg = cJSON_CreateObject();
        cJSON_AddStringToObject(user_msg, "role", "user");
        cJSON_AddStringToObject(user_msg, "content", text);
        cJSON_AddItemToArray(messages, user_msg);

        cJSON_AddItemToObject(request, "messages", messages);
        cJSON_AddNumberToObject(request, "temperature", 0.8);
        cJSON_AddNumberToObject(request, "max_tokens", 4000);
        cJSON_AddTrueToObject(request, "stream");

        cJSON *extra = cJSON_CreateObject();
        cJSON_AddFalseToObject(extra, "reason");
        cJSON_AddItemToObject(request, "extra_body", extra);

        char *request_body = cJSON_Print(request);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request_body);

        // 设置回调函数
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

        // 添加调试和SSL选项（测试用）
        //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);          // 启用详细日志
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);   // 禁用证书验证
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);   // 禁用主机名验证
        
        // 执行请求
        res = curl_easy_perform(curl);

        // 检查错误
        if (res != CURLE_OK) {
            fprintf(stderr, "请求失败: %s\n", curl_easy_strerror(res));
        }

        // 清理
        free(request_body);
        cJSON_Delete(request);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }
    printf("\n");
    free(chunk.memory);
    curl_global_cleanup();
}

void mylog(int lognumber, char* argv[]){
    switch(lognumber){
        case PARAMETER_ERROR:
            printf("checkcode: '%s'参数使用错误!", argv[1]);
            break;
        case FILE_NOT_FOUND:
            printf("checkcode: '%s'文件不存在!", argv[1]);
            break;
        case FEW_PARAMETERS:
            printf("checkcode: 参数不够!");
            break;
        case OPEN_FILE_ERROR:
            printf("checkcode: '%s'文件打开失败!", argv[1]);
            break;
        case FILE_NULL:
            printf("checkcode: '%s'空文件!", argv[1]);
            break;
        case FILE_READ_ERROR:
            printf("checkcode: '%s'读取字节数与真实字节数不一致!", argv[1]);
            break;
        case USER_TEXT_NULL:
            printf("checkcode: '%s'后的用户输入不能为空!", argv[1]);
            break;
        case MODEL_ERROR:
            printf("checkcode: '%s'模型选择错误!", argv[2]);
            break;
    }
    printf("\r\n");
    printf("尝试使用 'checkcode --help' 获取信息");
    printf("\r\n");
}